package edu.nf.llmtest.service.Listenter;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.nf.llmtest.common.config.RabbitConfig;
import edu.nf.llmtest.service.Handler.MessageHandler;
import edu.nf.llmtest.service.factory.HandlerFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpRejectAndDontRequeueException;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;

/**
 * @ Author bin
 * @ Create  2025/10/27 上午10:57
 **/
@Service
@RequiredArgsConstructor
@Slf4j
public class RabbitMqListener {
    private final HandlerFactory handlerFactory;

    private final ObjectMapper mapper = new ObjectMapper();

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = RabbitConfig.QUEUE_NAME, durable = "false"),
            exchange = @Exchange(name = RabbitConfig.EXCHANGE_NAME, type = ExchangeTypes.DIRECT),
            key = RabbitConfig.ROUTING_KEY))
    public void onMessage(Message message) {
        try {
            String json = new String(message.getBody(), StandardCharsets.UTF_8);
            JsonNode node = mapper.readTree(json);
            String type = node.get("type").asText();

            MessageHandler handler = handlerFactory.getHandler(type);
            if (handler == null) {
                log.info("⚠️ 未找到处理器: {}" , type);
                return;
            }

            handler.handle(message);
        } catch (Exception e) {
            throw new AmqpRejectAndDontRequeueException("处理失败，不重回队列", e);
        }
    }

    private void handleUnknownType(String type, String rawMessage) {
        // 日志、持久化或发到DLQ
        System.err.println("Unknown message type: " + type);
    }

    private void handleProcessingError(Exception e, String rawMessage) {
        // 日志，或抛出异常让 Rabbit 自动重试（视配置而定）
        e.printStackTrace();
    }
}
